#ifndef _FPGA_ENCODE_H_
#define _FPGA_ENCODE_H_


#ifdef __cplusplus
extern "C" {
#endif
#define ARRAY_SIZE(a)          (sizeof(a) / sizeof((a)[0]))
//*****************************************************************************
/* OTDR 测试数据命令 */
#define OTDR_RETURN            (0xf0)
#define OTDR_RESET             (0xe0)

#define OTDR_PARAM             (0x10)
#define OTDR_START             (0x11)
#define OTDR_STOP              (0x12)
#define OTDR_IS_FINISH         (0x13)
#define OTDR_REDLASER          (0x14)
#define OTDR_ALIVE             (0xa0)
#define OTDR_COM_LASER         (0x15)
#define OTDR_VER               (0xa1)
#define OTDR_ROTDR             (0x20)
#define OTDR_APD_TEMP          (0x21)
#define OTDR_POWER             (0x22)
#define OTDR_PULSE_ENCODE      (0x23)

/* TMS400 等系统专有命令 */
#define OTDR_ALARM_APPEAR      (0x25)  // TMS400 告警输出 数码管显示
#define OTDR_ALARM_DISAPPEAR   (0x26)  // TMS400 告警取消

//*****************************************************************************
/* TF500私有命令 测试数据命令 */
#define OTDR_WD_REG            (0x27)  // TF500 对寄存器芯片进行写操作 2018-8-27
#define OTDR_RD_REG            (0x28)  // TF500 对寄存器芯片进行读操作 2018-8-27
//*****************************************************************************
/* OCID 命令 */
#define OCID_PARAM             (0x30)
#define OCID_LEVEL             (0x31)
#define OCID_START             (0x32)
#define OCID_STOP              OTDR_STOP
#define OCID_READ_DATA         (0x33)

// #define OCVL_PARAM              (OTDR_PARAM)
#define OCVL_IS_FINISH         (OTDR_IS_FINISH)
#define OCVL_START             (0xbb)
#define OCVL_STOP              (0xbb)  // 未定义
#define OCVL_READ_DATA         (0xbb)

/* 数据错误试着次数 */
#define RETRY                  (3)


#define UNUSE_BIT              (0)

#define SW_UNUSE               (0)
#define SW_RESERVE             (1)
#define SW_AMP                 (2)
#define SW_APD                 (3)
#define SW_POWER               (4)  // 暂时不控制

//*******************不同光耦就修改这个 *******************
// 将 32bit 的 amp 逻辑值映射到与硬件相关的 8bit 上
// amp 遵循权重越低，放大倍数效果越小，encode大小与放大倍数没直接关系

/*
    amp xxxxxxxx xxxxxxxx xxxxxxbb xxxxbbbb
    encode  ssssSSxx
          |  |-- LV2
          |----- LV1
*/

// #ifdef CONFIG_CHIP_FPGA_2016
// 有效电平
#define CFG_AMP_LOW_ACTIVE_LV1 (1)
#define CFG_AMP_LOW_ACTIVE_LV2 (0)
#define CFG_AMP_LOW_ACTIVE_LV3 (0)
#define CFG_AMP_LOW_ACTIVE_LV4 (0)

// 32bit 转换成 8bit 对应级别掩码，掩码不为 0 表示使用该级别
#define CFG_AMP_MASK_LV1       (0xf0)
#define CFG_AMP_MASK_LV2       (0x0c)
#define CFG_AMP_MASK_LV3       (0x00)
#define CFG_AMP_MASK_LV4       (0x00)

// 32bit 各 bit 对应 8bit 哪几位，没用的填 UNUSE_BIT
#define CFG_AMP_B0_TO_SW       (1 << 7)  // bit0 映射到amp编码值 0x80上
#define CFG_AMP_B1_TO_SW       (1 << 6)
#define CFG_AMP_B2_TO_SW       (1 << 5)
#define CFG_AMP_B3_TO_SW       (1 << 4)
#define CFG_AMP_B4_TO_SW       (UNUSE_BIT)
#define CFG_AMP_B5_TO_SW       (UNUSE_BIT)
#define CFG_AMP_B6_TO_SW       (UNUSE_BIT)
#define CFG_AMP_B7_TO_SW       (UNUSE_BIT)

#define CFG_AMP_B8_TO_SW       (1 << 3)
#define CFG_AMP_B9_TO_SW       (1 << 2)
#define CFG_AMP_B10_TO_SW      (UNUSE_BIT)
#define CFG_AMP_B11_TO_SW      (UNUSE_BIT)
#define CFG_AMP_B12_TO_SW      (UNUSE_BIT)
#define CFG_AMP_B13_TO_SW      (UNUSE_BIT)
#define CFG_AMP_B14_TO_SW      (UNUSE_BIT)
#define CFG_AMP_B15_TO_SW      (UNUSE_BIT)

#define CFG_AMP_B16_TO_SW      (UNUSE_BIT)
#define CFG_AMP_B17_TO_SW      (UNUSE_BIT)
#define CFG_AMP_B18_TO_SW      (UNUSE_BIT)
#define CFG_AMP_B19_TO_SW      (UNUSE_BIT)
#define CFG_AMP_B20_TO_SW      (UNUSE_BIT)
#define CFG_AMP_B21_TO_SW      (UNUSE_BIT)
#define CFG_AMP_B22_TO_SW      (UNUSE_BIT)
#define CFG_AMP_B23_TO_SW      (UNUSE_BIT)

#define CFG_AMP_B24_TO_SW      (UNUSE_BIT)
#define CFG_AMP_B25_TO_SW      (UNUSE_BIT)
#define CFG_AMP_B26_TO_SW      (UNUSE_BIT)
#define CFG_AMP_B27_TO_SW      (UNUSE_BIT)
#define CFG_AMP_B28_TO_SW      (UNUSE_BIT)
#define CFG_AMP_B29_TO_SW      (UNUSE_BIT)
#define CFG_AMP_B30_TO_SW      (UNUSE_BIT)
#define CFG_AMP_B31_TO_SW      (UNUSE_BIT)


/*************************************************************
  APD
*/
// 低电平有效
#define CFG_APD_LOW_ACTIVE     (0)

// APD 电压掩码
#define CFG_APD_MASK           (0x00000007)

// APD 开关
#define CFG_APD_B0_TO_SW       (1 << 0)
#define CFG_APD_B1_TO_SW       (1 << 1)
#define CFG_APD_B2_TO_SW       (1 << 2)
#define CFG_APD_B3_TO_SW       (UNUSE_BIT)
#define CFG_APD_B4_TO_SW       (UNUSE_BIT)
#define CFG_APD_B5_TO_SW       (UNUSE_BIT)
#define CFG_APD_B6_TO_SW       (UNUSE_BIT)
#define CFG_APD_B7_TO_SW       (UNUSE_BIT)

/*************************************************************
  switch 开关对应
  需要使能 CONFIG_DBG_OTDR_SW
*/
#define CFG_SW0                 \
    {                           \
	SW_RESERVE, (UNUSE_BIT) \
    }
#define CFG_SW1          \
    {                    \
	SW_AMP, (1 << 7) \
    }
#define CFG_SW2          \
    {                    \
	SW_AMP, (1 << 6) \
    }
#define CFG_SW3          \
    {                    \
	SW_AMP, (1 << 5) \
    }
#define CFG_SW4          \
    {                    \
	SW_AMP, (1 << 4) \
    }
#define CFG_SW5          \
    {                    \
	SW_AMP, (1 << 3) \
    }
#define CFG_SW6          \
    {                    \
	SW_AMP, (1 << 2) \
    }
#define CFG_SW7          \
    {                    \
	SW_APD, (1 << 0) \
    }
#define CFG_SW8          \
    {                    \
	SW_APD, (1 << 1) \
    }
#define CFG_SW9          \
    {                    \
	SW_APD, (1 << 2) \
    }
#define CFG_SW10              \
    {                         \
	SW_UNUSE, (UNUSE_BIT) \
    }
#define CFG_SW11              \
    {                         \
	SW_UNUSE, (UNUSE_BIT) \
    }
#define CFG_SW12              \
    {                         \
	SW_UNUSE, (UNUSE_BIT) \
    }
#define CFG_SW13              \
    {                         \
	SW_UNUSE, (UNUSE_BIT) \
    }
#define CFG_SW14              \
    {                         \
	SW_UNUSE, (UNUSE_BIT) \
    }
#define CFG_SW15              \
    {                         \
	SW_UNUSE, (UNUSE_BIT) \
    }


//**************************************************************
// 有效参数等待 FPGA 解释
// 未必是下面的有效值

#define UNUSE_BIT          (0)


#define AMP_LOW_ACTIVE_LV1 (CFG_AMP_LOW_ACTIVE_LV1)  // 光耦开关低电平有效
#define AMP_LOW_ACTIVE_LV2 (CFG_AMP_LOW_ACTIVE_LV2)
#define AMP_LOW_ACTIVE_LV3 (CFG_AMP_LOW_ACTIVE_LV3)
#define AMP_LOW_ACTIVE_LV4 (CFG_AMP_LOW_ACTIVE_LV4)


#define AMP_B0_TO_SW       (CFG_AMP_B0_TO_SW)  // bit0 映射到amp编码值 0x80上
#define AMP_B1_TO_SW       (CFG_AMP_B1_TO_SW)
#define AMP_B2_TO_SW       (CFG_AMP_B2_TO_SW)
#define AMP_B3_TO_SW       (CFG_AMP_B3_TO_SW)
#define AMP_B4_TO_SW       (CFG_AMP_B4_TO_SW)
#define AMP_B5_TO_SW       (CFG_AMP_B5_TO_SW)
#define AMP_B6_TO_SW       (CFG_AMP_B6_TO_SW)
#define AMP_B7_TO_SW       (CFG_AMP_B7_TO_SW)

#define AMP_B8_TO_SW       (CFG_AMP_B8_TO_SW)
#define AMP_B9_TO_SW       (CFG_AMP_B9_TO_SW)
#define AMP_B10_TO_SW      (CFG_AMP_B10_TO_SW)
#define AMP_B11_TO_SW      (CFG_AMP_B11_TO_SW)
#define AMP_B12_TO_SW      (CFG_AMP_B12_TO_SW)
#define AMP_B13_TO_SW      (CFG_AMP_B13_TO_SW)
#define AMP_B14_TO_SW      (CFG_AMP_B14_TO_SW)
#define AMP_B15_TO_SW      (CFG_AMP_B15_TO_SW)

#define AMP_B16_TO_SW      (CFG_AMP_B16_TO_SW)
#define AMP_B17_TO_SW      (CFG_AMP_B17_TO_SW)
#define AMP_B18_TO_SW      (CFG_AMP_B18_TO_SW)
#define AMP_B19_TO_SW      (CFG_AMP_B19_TO_SW)
#define AMP_B20_TO_SW      (CFG_AMP_B20_TO_SW)
#define AMP_B21_TO_SW      (CFG_AMP_B21_TO_SW)
#define AMP_B22_TO_SW      (CFG_AMP_B22_TO_SW)
#define AMP_B23_TO_SW      (CFG_AMP_B23_TO_SW)

#define AMP_B24_TO_SW      (CFG_AMP_B24_TO_SW)
#define AMP_B25_TO_SW      (CFG_AMP_B25_TO_SW)
#define AMP_B26_TO_SW      (CFG_AMP_B26_TO_SW)
#define AMP_B27_TO_SW      (CFG_AMP_B27_TO_SW)
#define AMP_B28_TO_SW      (CFG_AMP_B28_TO_SW)
#define AMP_B29_TO_SW      (CFG_AMP_B29_TO_SW)
#define AMP_B30_TO_SW      (CFG_AMP_B30_TO_SW)
#define AMP_B31_TO_SW      (CFG_AMP_B31_TO_SW)

// amp 各放大级别在 encode 里的有效掩码
#define AMP_MASK_LV1       (CFG_AMP_MASK_LV1)
#define AMP_MASK_LV2       (CFG_AMP_MASK_LV2)
#define AMP_MASK_LV3       (CFG_AMP_MASK_LV3)
#define AMP_MASK_LV4       (CFG_AMP_MASK_LV4)

/*
  struct _fpga_test_param_tx 内容依据《TR600plus—CPU与FPGA通信命令协议.doc》
  2016-11-24 协议格式而定

  实际发送 "数据段" 内容
 转译 struct fpga_test_param  用fpga_otdr_param() 屏蔽协议层、与协议无关
*/

struct _fpga_test_param_tx
{
    unsigned short laser;  ///< 激光器通道
    unsigned short pulse;
    unsigned short dist;
#if CONFIG_PROTOCAL_TR600_SPI
    unsigned char freq;
    unsigned char adopt_pt;
    short         add_cnt;
#endif
    unsigned short add_ms;
    char           power;
    char           amp;
    char           apd_vol;
    char           slot;
    char           ch;  ///< 光开关通道
    char           unuse1, unuse2, unuse3;
};


/*
  struct _fpga_test_param_tx 内容依据《TR600plus—CPU与FPGA通信命令协议.doc》
  2016-11-24 协议格式而定

  实际发送 "数据段" 内容
 转译 struct fpga_test_param  用fpga_otdr_param() 屏蔽协议层、与协议无关
*/

struct _fpga_ocid_param_tx
{
    char  ch;
    short post;  // 位置（由FPGA自己决定起始、结束位置）
} __attribute__((__packed__));


/*****************************************************************************
    设置 OTDR 测试参数 功能入口 fpga_otdr_param

 fpga_otdr_param
    _encode_dist_2_pulse/_encode_self_pulse
    _encode_dist_2_sample_freq/_encode_self_sample_freq
    _encode_laser
    _encode_adopt
    _encode_add_cnt
    _encode_power
    _encode_amp
    _encode_apd_vol
    _encode_slot
    _encode_ch
*****************************************************************************/


short          _encode_laser(struct fpga_test_param *val);
short          _encode_dist_2_pulse(struct fpga_test_param *val);
short          _encode_self_pulse(struct fpga_test_param *val);
char           _encode_dist_2_sample_freq(struct fpga_test_param *val);
char           _encode_self_sample_freq(struct fpga_test_param *val);
char           _encode_adopt(struct fpga_test_param *val);
short          _encode_add_cnt(struct fpga_test_param *val);
char           _encode_amp(struct fpga_test_param *val);
char           _encode_apd_vol(struct fpga_test_param *val);
char           _encode_power(struct fpga_test_param *val);
char           _encode_slot(struct fpga_test_param *val);
char           _encode_ch(struct fpga_test_param *val);
unsigned short _encode_add_ms(struct fpga_test_param *val);
unsigned long  _decode_freq(char *rbuf);
unsigned short _decode_adopt_pt(char *rbuf);

short _encode_pulse(struct fpga_test_param *val);
short _encode_dist(struct fpga_test_param *val);
short _encode_self_dist(struct fpga_test_param *val);
#ifdef __cplusplus
}
#endif
#endif
